﻿using System;
using System.Threading;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sanford.Collections;
using Sanford.Multimedia;
using Sanford.Threading;
using Sanford.Multimedia.Midi;
using Sanford.Multimedia.Timers;
using System.Windows.Threading;

namespace GentlyWeep
{
    

    class Midicon
    {
        private int bpm = 1000;
        private int IDmidi = 0;
        private int keyUp = 0;
        private int timeSig = 0;
        private String genre = "";
        private OutputDevice outDevice;
        private int outDeviceID = 0;
        private int volume = 100;

        ChannelMessageBuilder builder;
        WeepEventArgs we = new WeepEventArgs();

        public Midicon()
        {
            outDevice = new OutputDevice(outDeviceID);
        }

        public int TimeSig
        {
            get { return timeSig; }
            set { timeSig = value; }
        }
        public int Volume
        {
            get { return volume; }
            set { volume = value; }
        }

        public int KeyUp
        {
            get { return keyUp; }
            set { keyUp = value; }
        }

        public int Bpm
        {
            get { return bpm; }
            set { bpm = value; }
        }

        public String Genre
        {
            get { return genre; }
            set { genre = value; }
        }

        public void metronome()
        {
            while (true)
            {
                
                outDevice.Send(new ChannelMessage(ChannelCommand.NoteOff, 0, 60, 127));
                outDevice.Send(new ChannelMessage(ChannelCommand.NoteOn, 9, 60, 127));
                Thread.Sleep(bpm);
            }
        }

        public void out_send(ChannelMessageEventArgs e)
        {
            if (e.Message.MidiChannel == 9) // Channel 9 is drums
            {
                builder = new ChannelMessageBuilder();
                builder.Command = e.Message.Command;
                builder.MidiChannel = e.Message.MidiChannel;
                builder.Data1 = e.Message.Data1;
                builder.Data2 = volume+27;
                builder.Build();
                outDevice.Send(builder.Result);
            }
            else
            {
                IDmidi = (e.Message.Data1 + keyUp);
                if (IDmidi < 0)
                {
                    IDmidi = 0;
                }
                builder = new ChannelMessageBuilder();
                builder.Command = e.Message.Command;
                builder.MidiChannel = e.Message.MidiChannel;
                builder.Data1 = e.Message.Data1;
                builder.Data2 = volume + 27;
                builder.Build();
                outDevice.Send(builder.Result);
            }

        }

        public void out_send2(WeepEventArgs we)
        {
            if (we.MidiChannel == 9) // Channel 9 is drums
            {
                builder = new ChannelMessageBuilder();
                builder.Command = ChannelCommand.NoteOn;// we.Command;
                builder.MidiChannel = we.MidiChannel;
                builder.Data1 = we.Data1;
                builder.Data2 = volume + 27;
                builder.Build();
                outDevice.Send(builder.Result);
            }
            else
            {
                IDmidi = (we.Data1 + keyUp);
                if (IDmidi < 0)
                {
                    IDmidi = 0;
                }
                builder = new ChannelMessageBuilder();
                builder.Command = ChannelCommand.NoteOn;//we.Command;
                builder.MidiChannel = we.MidiChannel;
                builder.Data1 = IDmidi;
                builder.Data2 = volume + 27;
                builder.Build();
                outDevice.Send(builder.Result);
            }

        }

        public void readMidi(Sequence seq)
        {
            List<string> list = new List<string>();
            foreach (Track t in seq)
            {

                Console.WriteLine("1");
                for (int i = 0; i < t.Count; i++)
                {
                    Console.Write(t.GetMidiEvent(i).MidiMessage.MessageType + " ] ");
                    if (t.GetMidiEvent(i).MidiMessage.Status >= 144 && t.GetMidiEvent(i).MidiMessage.Status <= 159) // note on
                    {
                        list.Add("+"    // เปิดโน้ต
                         + i            // จำนวน
                         + "|" + (t.GetMidiEvent(i).MidiMessage.GetBytes()[0]-144) //status 
                         + "|" + t.GetMidiEvent(i).MidiMessage.GetBytes()[1] //ID midi
                         + "|" + t.GetMidiEvent(i).MidiMessage.GetBytes()[2] //Data 2
                         + "|" + t.GetMidiEvent(i).AbsoluteTicks); // time.tick
                        if (list.Count>0)
                        {
                            Console.WriteLine(list[list.Count-1]);
                        }
                        
                    }
                    else if (t.GetMidiEvent(i).MidiMessage.Status >= 128 && t.GetMidiEvent(i).MidiMessage.Status <= 143) // note off
                    {
                        list.Add("-"    //ปิดโน้ต
                         + i            //จำนวน
                         + "|" + (t.GetMidiEvent(i).MidiMessage.GetBytes()[0] - 128) //status 
                         + "|" + t.GetMidiEvent(i).MidiMessage.GetBytes()[1] //ID midi
                         + "|" + t.GetMidiEvent(i).MidiMessage.GetBytes()[2] //Data 2
                         + "|" + t.GetMidiEvent(i).AbsoluteTicks); // time.tick
                        if (list.Count > 0)
                        {
                            Console.WriteLine(list[list.Count - 1]);
                        }
                    }
                    else
                    {
                         
                        for (int j = t.GetMidiEvent(i).MidiMessage.GetBytes().Length-1; j >= 0; j--)
                        {
                            Console.Write(t.GetMidiEvent(i).MidiMessage.GetBytes()[j]+" i "); 
                        }
                        Console.WriteLine();
                    }
                }
            }
        }

        public List<string> selectDrum()
        {
            List<string> line = new List<string>();
            int count = 0;
            for (int i = 0; i < 0; i--)
            {
                line.Add("Midi//" + Genre + "//" + i + "-" + bpm + "-C.mid");
            }

            if (line.Count == 0)
            {
                line.Add("null");
            }
            return line;
        }

        public List<string> selectBass()
        {
            List<string> line = new List<string>();
            int count = 0;
            for (int i = 0; i < 0; i--)
            {
                line.Add("Midi//" + Genre + "//" + i + "-" + bpm + "-C.mid");
            }

            if (line.Count == 0)
            {
                line.Add("null");
            }
            return line;
        }
    }
}
